00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef _fallback_matrix_operations_hpp_
00022 #define _fallback_matrix_operations_hpp_
00023
00024 #include "matrix.hpp"
00025
00026 namespace gridpack {
00027 namespace math {
00028 namespace fallback {
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 template <typename T, typename I>
00040 void diagonal(const MatrixT<T, I>& A, VectorT<T, I>& d)
00041 {
00042 I lo, hi;
00043 A.localRowRange(lo, hi);
00044 for (I i = lo; i < hi; ++i) {
00045 T x;
00046 A.getElement(i, i, x);
00047 d.setElement(i, x);
00048 }
00049 d.ready();
00050 }
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 template <typename T, typename I>
00063 MatrixT<T, I> *diagonal(const VectorT<T, I>& x,
00064 const MatrixStorageType& stype = Sparse)
00065 {
00066 MatrixT<T, I> *result;
00067 result = new MatrixT<T, I>(x.communicator(), x.localSize(), x.localSize(), stype);
00068
00069 I lo, hi;
00070 x.localIndexRange(lo, hi);
00071
00072 for (I i = lo; i < hi; ++i) {
00073 T v;
00074 x.getElement(i, v);
00075 result->setElement(i, i, v);
00076 }
00077 result->ready();
00078 return result;
00079 }
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092 template <typename T, typename I>
00093 void
00094 column(const MatrixT<T, I>& A, const I& cidx, VectorT<T, I>& c)
00095 {
00096 I lo, hi;
00097 A.localRowRange(lo, hi);
00098 for (I i = lo; i < hi; ++i) {
00099 T x;
00100 A.getElement(i, cidx, x);
00101 c.setElement(i, x);
00102 }
00103 c.ready();
00104 }
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114 template <typename T, typename I>
00115 void
00116 multiplyDiagonal(MatrixT<T, I>& A, const VectorT<T, I>& x)
00117 {
00118 I lrows(A.localRows());
00119 std::vector<T> dnew(lrows);
00120 I lo, hi;
00121 x.localIndexRange(lo, hi);
00122 for (I i = lo; i < hi; ++i) {
00123 T v;
00124 x.getElement(i, v);
00125 dnew[i-lo] = v;
00126 A.getElement(i, i, v);
00127 dnew[i-lo] *= v;
00128 }
00129
00130 for (I i = lo; i < hi; ++i) {
00131 T v(dnew[i-lo]);
00132 A.setElement(i, i, v);
00133 }
00134
00135 A.ready();
00136 }
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147 template <typename T, typename I>
00148 void
00149 addDiagonal(MatrixT<T, I>& A, const VectorT<T, I>& x)
00150 {
00151 I lo, hi;
00152 x.localIndexRange(lo, hi);
00153 for (I i = lo; i < hi; ++i) {
00154 T v;
00155 x.getElement(i, v);
00156 A.addElement(i, i, v);
00157 }
00158 A.ready();
00159 }
00160
00161
00162
00163
00164
00165 template <typename T, typename I>
00166 void
00167 denseMatrixMultiply(const MatrixT<T, I>& A, const MatrixT<T, I>& B, MatrixT<T, I>& C)
00168 {
00169 BOOST_ASSERT(A.rows() == C.rows());
00170 BOOST_ASSERT(B.cols() == C.cols());
00171 boost::scoped_ptr< VectorT<T, I> >
00172 bc(new VectorT<T, I>(B.communicator(), B.localRows())),
00173 rc(new VectorT<T, I>(C.communicator(), C.localRows()));
00174 int lo, hi;
00175 rc->localIndexRange(lo, hi);
00176 for (int j = 0; j < B.cols(); ++j) {
00177 math::column(B, j, *bc);
00178 math::multiply(A, *bc, *rc);
00179 for (int i = lo; i < hi; ++i) {
00180 typename VectorT<T, I>::TheType v;
00181 rc->getElement(i, v);
00182 C.setElement(i, j, v);
00183 }
00184 }
00185 C.ready();
00186 }
00187
00188 template <typename T, typename I>
00189 MatrixT<T, I> *
00190 denseMatrixMultiply(const MatrixT<T, I>& A, const MatrixT<T, I>& B)
00191 {
00192 BOOST_ASSERT(A.cols() == B.rows());
00193 BOOST_ASSERT(A.localCols() == B.localRows());
00194 MatrixT<T, I> *C(MatrixT<T, I>::createDense(A.communicator(),
00195 A.rows(), B.cols(),
00196 A.localRows(), B.localCols()));
00197 denseMatrixMultiply(A, B, *C);
00198 return C;
00199 }
00200
00201
00202 }
00203 }
00204 }
00205
00206
00207 #endif